<template>
  <div
    :class="cn('cg-select', SelectVariants({ size }), props.class)"
    @mouseenter="inputHovering = true"
    @mouseleave="inputHovering = false"
  >
    <input
      :class="cn('cg-select-input', SelectInputVariants({ size }))"
      ref="inputRef"
      type="text"
      :placeholder="placeholder"
      readonly
      :value="inputShow"
      @click.stop="toggleMenu"
      v-clickoutside="handleClose"
    />
    <span :class="cn('cg-select-suffix', SelectSuffixVariants({ size }))">
      <svg-icon v-show="!showClose" icon-name="down"></svg-icon>
      <svg-icon v-if="showClose" icon-name="close" @click="handleClearClick"></svg-icon>
    </span>

    <div ref="popper" v-show="visible" :class="cn('cg-select-menu', SelectMenuVariants({ size }))">
      <cg-scrollbar ref="scrollbar" tag="div">
        <div
          v-for="item in options"
          :key="item.id"
          :class="cn('cg-select-option', SelectOptionVariants({ size, active: item.id === data }))"
          @click="handleSelect(item)"
        >
          {{ item.name }}
        </div>
      </cg-scrollbar>
    </div>
  </div>
</template>

<script setup lang="ts">
import { type HTMLAttributes, ref, computed, watch, onMounted } from 'vue'
import { switchValue } from '../../tools'
import { cn } from '../../lib/utils'
import {
  SelectVariants,
  SelectInputVariants,
  SelectMenuVariants,
  SelectOptionVariants,
  SelectSuffixVariants
} from './tools'

defineOptions({
  name: 'cg-select'
})

interface Props {
  size?: SelectVariants['size']
  class?: HTMLAttributes['class']
  modelValue: string | number | undefined
  placeholder?: string
  options: Array<{ id: string | number; name: string }>
}
// 定义props
const props = withDefaults(defineProps<Props>(), {})

// 定义emits
const emit = defineEmits<{
  (e: 'update:modelValue', value: string | number | undefined): void
  (e: 'change', value: string | number | undefined): void
  (e: 'clear'): void
}>()

// 响应式数据
const data = ref(props.modelValue)
const visible = ref(false)
const inputHovering = ref(false)

// 计算属性
const inputShow = computed(() => {
  return switchValue(data.value, props.options, 'id').name
})

const showClose = computed(() => {
  if (inputHovering.value && Array.isArray(props.options)) {
    return props.options.findIndex((option) => option['id'] === data.value) >= 0
  }
  return false
})

// 监听props变化
watch(
  () => props.modelValue,
  (val) => {
    data.value = val
  }
)

onMounted(() => {
  console.log('options', props.options)
})

// 方法
const handleClose = () => {
  visible.value = false
}

const handleInput = () => {
  visible.value = true
}

const toggleMenu = () => {
  visible.value = !visible.value
}

const handleSelect = (item: { id: string | number; name: string }) => {
  data.value = item.id
  emit('update:modelValue', data.value)
  emit('change', data.value)
}

const handleClearClick = (event: MouseEvent) => {
  event.stopPropagation()
  emit('update:modelValue', undefined)
  emit('change', undefined)
  visible.value = false
  emit('clear')
}

// 组件引用
const inputRef = ref<HTMLInputElement | null>(null)
const popper = ref<HTMLDivElement | null>(null)
const scrollbar = ref<HTMLElement | null>(null)
</script>

<style lang="scss">
// @use "./style.scss";
</style>
